package main

import "go-leetcode/leetcode/utils"

// 25. K 个一组翻转链表
func main() {
	//listNode := utils.GetListNodeByArray([]int{5, 6, 1, 8, 4, 5})
	//target := 4
	listNode := utils.GetListNodeByArray([]int{1, 2, 3, 4, 5})
	target := 3

	pointListNode := listNode
	for pointListNode != nil {
		print(pointListNode.Val, " ")
		pointListNode = pointListNode.Next
	}
	println(" ")

	node := reverseKGroup(listNode, target)

	pointResNode := node
	println("转换为")
	for pointResNode != nil {
		print(pointResNode.Val, " ")
		pointResNode = pointResNode.Next
	}
	return
}

func reverseKGroup(head *utils.ListNode, k int) *utils.ListNode {
	if k == 1 {
		return head
	}
	prev := head

	for i := 1; i < k; i++ {
		if prev == nil || prev.Next == nil { // 说明不足k，不翻转了
			return head
		}
		prev = prev.Next
	}
	appendNodes := prev.Next
	prev.Next = nil

	// head指向头，prev指向尾， 翻转后，prev指向头，head指向尾
	var point1 *utils.ListNode
	point2 := head
	for point2 != nil {
		next := point2.Next
		point2.Next = point1
		point1 = point2
		point2 = next
	}

	head.Next = reverseKGroup(appendNodes, k)

	return prev
}

// 给你链表的头节点 head ，每 k 个节点一组进行翻转，请你返回修改后的链表。
//
//k 是一个正整数，它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍，那么请将最后剩余的节点保持原有顺序。
//
//你不能只是单纯的改变节点内部的值，而是需要实际进行节点交换。
//
//示例 1：
//
//输入：head = [1,2,3,4,5], k = 2
//输出：[2,1,4,3,5]
//示例 2：
//
//输入：head = [1,2,3,4,5], k = 3
//输出：[3,2,1,4,5]
//
//提示：
//链表中的节点数目为 n
//1 <= k <= n <= 5000
//0 <= Node.val <= 1000
//
//进阶：你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗？
